package com.hilinos.common.common.handler;

import com.hilinos.common.common.ReturnCode;
import com.hilinos.common.util.AssertUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class RequestTokenHandler implements HandlerInterceptor {

    private final ITokenHandler iTokenHandler;

    public RequestTokenHandler(ITokenHandler iTokenHandler) {
        this.iTokenHandler = iTokenHandler;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (HttpMethod.OPTIONS.name().equals(request.getMethod())) {
            return true;
        }

        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;

        NoToken noToken = handlerMethod.getMethodAnnotation(NoToken.class);

        if (noToken != null && !noToken.needToken()) {
            return true;
        }

        // 如果没有认证规则，直接放行
        if (iTokenHandler == null) {
            return true;
        }

        NoTokenEntity noTokenEntity = new NoTokenEntity();
        if (noToken == null) {
            noTokenEntity.setNeedToken(true);
            noTokenEntity.setOnlySuperAdmin(false);
        } else {
            noTokenEntity.setNeedToken(noTokenEntity.isNeedToken());
            noTokenEntity.setOnlySuperAdmin(noToken.onlySuperAdmin());
        }

        boolean authResult = iTokenHandler.checkToken(request.getHeader("token"), request, handlerMethod, noTokenEntity);

        if (authResult) {
            return true;
        }
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : request.getCookies()) {
                if ("token".equals(cookie.getName())) {
                    authResult = iTokenHandler.checkToken(cookie.getValue(), request, handlerMethod, noTokenEntity);
                }
            }
        }
        AssertUtils.isRex(authResult, ReturnCode.AUTH_ERROR);
        return authResult;
    }

}
